<template>
  <div id="g-tree-vue">
    <el-tree ref="gtree" @node-contextmenu="rightClick" v-bind="Object.assign(initAttrs, $attrs)" v-on="$listeners">
      <template v-for="(_, name) in $scopedSlots" v-slot:[name]="data">
        <slot :name="name" v-bind="data"></slot>
      </template>
    </el-tree>
    <context-menu id="context-menu" ref="ctxMenu" v-if="showBtn.add || showBtn.del || showBtn.edit || showBtn.refresh">
      <div class="ct_item">
        <slot name="tree-form-start" :data="currData"></slot>
      </div>
      <div class="ct_item" v-if="showBtn.add">
        <el-button @click="addNextLevel()" v-bind="globlSetting.treeAdd">{{ globlSetting.treeAdd.text
          }}</el-button>
      </div>
      <div class="ct_item" v-if="showBtn.edit">
        <el-button @click="updateTreeNode()" v-bind="globlSetting.treeEdit">{{ globlSetting.treeEdit.text
          }}</el-button>
      </div>
      <div class="ct_item">
        <slot name="tree-form-mid" :data="currData"></slot>
      </div>
      <div class="ct_item" v-if="showBtn.del">
        <el-button @click="delTreeItem()" v-bind="globlSetting.treeDel">{{ globlSetting.treeDel.text
          }}</el-button>
      </div>
      <div class="ct_item" v-if="showBtn.refresh">
        <el-button @click="refresh()" v-bind="globlSetting.treeRefresh">{{ globlSetting.treeRefresh.text
          }}</el-button>
      </div>
      <div class="ct_item">
        <slot name="tree-form-end" :data="currData"></slot>
      </div>
    </context-menu>
  </div>
</template>

<script>
import vue from 'vue';
import contextMenu from "vue-context-menu";
import add from "./add.vue";
export default {
  name: "g-tree",
  components: { contextMenu, add },
  props: {
    "tree-form": {
      type: Object,
      default: () => { }
    },
    'menu-item-buttons': {
      type: Object,
      default: () => { }
    }
  },
  data() {
    return {
      defaultTreeForm: {
        pid: { title: "上级编号", edit: false },
        plabel: { title: '上级', disable: true },
        id: { title: "编号", edit: false },
        label: { title: "名称", required: true },
        isLeaf: { title: '是否是子节点', edit: false },
        disabled: { title: '是否禁用', edit: false },
        children: { title: '子节点', edit: false }
      },
      initAttrs: {
        "node-key": "id",
        "icon-class": "el-icon-caret-right",
        "highlight-current": true,
        "expand-on-click-node": false,
        "check-on-click-node": true,
        "default-expanded-keys": [0],
        lazy: false,
      },
      showBtn: {
        add: true,
        edit: true,
        del: true,
        refresh: true,
      },
      currNode: undefined,
      currData: undefined,
      currTreeForm: undefined,
      currMenuItemButtons: Object.assign({
        add: this.globlSetting.treeAdd,
        edit: this.globlSetting.treeEdit,
        delete: this.globlSetting.treeDel,
        refresh: this.globlSetting.treeRefresh,
      }, this.menuItemButtons)
    };
  },
  methods: {
    rightClick(event, data, node, self) {
      this.currNode = node;
      this.currData = data;
      this.$emit(
        "g-node-contextmenu",
        {
          event,
          data,
          node,
          self,
        },
        (qx) => {
          this.showBtn = Object.assign(this.showBtn, qx);
        }
      );
      this.$refs.ctxMenu.open();
      event.preventDefault();
    },
    addNextLevel() {
      this.currTreeForm = Object.assign({
        formInfo: {
          pid: this.currData?.id,
          plabel: this.currData?.label,
          label: ''
        },
        width: 450,
        title: "增加下级",
      }, this.treeForm);
      this.currTreeForm.formAttrs = Object.assign(this.defaultTreeForm,
        this.treeForm && this.treeForm.formAttrs ? this.treeForm.formAttrs : {});
      this.currTreeForm.formAttrs.plabel.edit = undefined;
      this.$emit("tree-open", this.currTreeForm);
      let ele = document.createElement('div');
      let vm = new vue({
        components: { add },
        render: (h) => h(add, {
          attrs: this.currTreeForm,
          on: {
            close: (val) => {
              vm.$destroy();
            },
            saveData: (data) => {
              this.$emit("tree-save", data, (result = true) => {
                if (result) {
                  vm.$destroy();
                }
                if (this.currNode) {
                  this.currNode.loaded = false;
                  this.currNode.expand();
                  this.$refs.gtree.append(data, this.currNode);
                }
              });
            },
          },
        }),
      }).$mount(ele);
    },
    updateTreeNode() {
      this.currTreeForm = Object.assign({
        formInfo: this.currData,
        width: 450,
        title: "编辑",
      }, this.treeForm);
      this.currTreeForm.formAttrs = Object.assign(this.defaultTreeForm,
        this.treeForm && this.treeForm.formAttrs ? this.treeForm.formAttrs : {});
      this.currTreeForm.formAttrs.plabel.edit = false;
      this.$emit("tree-open", this.currTreeForm);
      let ele = document.createElement('div');
      let vm = new vue({
        components: { add },
        render: (h) => h(add, {
          attrs: this.currTreeForm,
          on: {
            close: () => {
              vm.$destroy();
            },
            saveData: (data) => {
              this.$emit("tree-save", data, (result = true) => {
                this.$set(this.currData, 'label', data.label)
                if (result) {
                  vm.$destroy();
                }
              });
            },
          },
        })
      }).$mount(ele);
    },
    delTreeItem() {
      this.$confirm("是否要删除这个项?", "提示", {
        type: "warning",
      })
        .then(() => {
          this.$emit("delete", this.currNode, (result) => {
            if (result === true) {
              this.$refs.gtree.remove(this.currNode);
            } else {
              this.$message.error(result);
            }
          });
        })
        .catch(() => { });
    },
    refresh() {
      this.currNode.loaded = false;
      this.currNode.expand();
    },

  },
  mounted() {

  },
};
</script>

<style lang="css" scoped>
.tree-menu {
  position: absolute;
  background-color: #fff;
  width: 120px;
  font-size: 12px;
  color: #444040;
  border-radius: 4px;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  border-radius: 3px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  white-space: nowrap;
  z-index: 1000;
}

.ct_item {
  display: block;
  line-height: 34px;
  text-align: left;
  border-radius: 3px;
}

.ct_item button {
  padding: 0 20px;
  height: 42px !important;
  width: 100% !important;
  text-align: left !important;
}

.ct_item:not(:last-child) {
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.ct_item:hover {
  cursor: pointer;
  background: blue;
  border-color: #66b1ff;
  color: #fff;
  width: 100%;
  border-radius: 3px;
}

.ct_item:hover button {
  color: #fff;
  font-weight: bold;
  padding: 0 20px;
  height: 42px !important;
  background: blue;
  width: 100% !important;
  text-align: left !important;
}
</style>


<style>
#g-tree-vue .el-tree-node__content {
  height: 36px !important;
  display: inline-flex;
  align-items: center;
  border-bottom: 1px dashed #dfe6ec !important;
  width: 100% !important;
  padding: 3px 10px;
}

#g-tree-vue .ctx-menu {
  padding: 0px;
}
</style>
